#include "Model/Calendar.hpp"
#include "Model/OneOccurenceRule.hpp"
#include "CalendarRuleTests.hpp"
#include <boost/test/auto_unit_test.hpp>

namespace
{
	using namespace Model;

BOOST_AUTO_TEST_CASE( testRuleOperations)
{
	OneOccurenceRule* pOneTimeRule = new OneOccurenceRule;
	Calendar::Time rStart( Calendar::Date( 2008, 12, 10)),
		rEnd( Calendar::Date( 2008, 12, 20));
	Calendar::Time cStart( Calendar::Date( 2008, 01, 01)),
		cEnd( Calendar::Date( 2009, 01, 01));
	pOneTimeRule->setInterval( rStart, rEnd);

	Calendar calendar( cStart, cEnd);
	BOOST_CHECK_EQUAL( cStart, calendar.minimumTime());
	BOOST_CHECK_EQUAL( cEnd, calendar.maximumTime());

	calendar.addRule( pOneTimeRule);
	BOOST_REQUIRE_EQUAL( 1, calendar.rules().size());
	BOOST_CHECK_EQUAL( pOneTimeRule, *calendar.rules().begin());
	BOOST_REQUIRE_EQUAL( 1, calendar.busyPeriods().size());
	CHECK_TIME_INTERVAL( rStart, rEnd, *calendar.busyPeriods().begin());

	calendar.removeRule( pOneTimeRule);
	BOOST_REQUIRE_EQUAL( 0, calendar.rules().size());
	delete pOneTimeRule;
}

// ---------------------------------------------------------------------------------------------------------------------

BOOST_AUTO_TEST_CASE( testSetCalendarMinimum)
{
	OneOccurenceRule* pOneTimeRule = new OneOccurenceRule;
	Calendar::Time times[]  = 
		{ 
			Calendar::Time( Calendar::Date( 2008, 12, 10)),
			Calendar::Time( Calendar::Date( 2008, 12, 12)),
			Calendar::Time( Calendar::Date( 2008, 12, 14)),
			Calendar::Time( Calendar::Date( 2008, 12, 16)),
			Calendar::Time( Calendar::Date( 2008, 12, 18)),
			Calendar::Time( Calendar::Date( 2008, 12, 20))
		};
	pOneTimeRule->setInterval( times[1], times[4]);

	Calendar calendar( times[0], times[5]);
	calendar.addRule( pOneTimeRule);
	
	calendar.setMinimumTime( times[2]);
	BOOST_REQUIRE_EQUAL( 1, calendar.busyPeriods().size());
	CHECK_TIME_INTERVAL( times[2], times[4], *calendar.busyPeriods().begin());
}

// ---------------------------------------------------------------------------------------------------------------------

BOOST_AUTO_TEST_CASE( testSetCalendarMaximum)
{
	OneOccurenceRule* pOneTimeRule = new OneOccurenceRule;
	Calendar::Time times[]  = 
	{ 
		Calendar::Time( Calendar::Date( 2008, 12, 10)),
		Calendar::Time( Calendar::Date( 2008, 12, 12)),
		Calendar::Time( Calendar::Date( 2008, 12, 14)),
		Calendar::Time( Calendar::Date( 2008, 12, 16)),
		Calendar::Time( Calendar::Date( 2008, 12, 18)),
		Calendar::Time( Calendar::Date( 2008, 12, 20))
	};
	pOneTimeRule->setInterval( times[1], times[4]);

	Calendar calendar( times[0], times[5]);
	calendar.addRule( pOneTimeRule);

	calendar.setMaximumTime( times[3]);
	BOOST_REQUIRE_EQUAL( 1, calendar.busyPeriods().size());
	CHECK_TIME_INTERVAL( times[1], times[3], *calendar.busyPeriods().begin());
}

// ---------------------------------------------------------------------------------------------------------------------


BOOST_AUTO_TEST_CASE( testExtendCalendar)
{
	OneOccurenceRule* pOneTimeRule = new OneOccurenceRule;
	Calendar::Time times[]  = 
	{ 
		Calendar::Time( Calendar::Date( 2008, 12, 10)),
		Calendar::Time( Calendar::Date( 2008, 12, 12)),
		Calendar::Time( Calendar::Date( 2008, 12, 14)),
		Calendar::Time( Calendar::Date( 2008, 12, 16)),
		Calendar::Time( Calendar::Date( 2008, 12, 18)),
		Calendar::Time( Calendar::Date( 2008, 12, 20))
	};
	pOneTimeRule->setInterval( times[1], times[4]);

	Calendar calendar( times[0], times[5]);
	calendar.addRule( pOneTimeRule);

	calendar.extendCalendar( times[2], times[3]);
	BOOST_REQUIRE_EQUAL( 1, calendar.busyPeriods().size());
	CHECK_TIME_INTERVAL( times[2], times[3], *calendar.busyPeriods().begin());
}

// ---------------------------------------------------------------------------------------------------------------------


} // namespace
